package com.micro.ai.auth.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.micro.ai.auth.dto.MenuCreateRequest;
import com.micro.ai.auth.dto.MenuDTO;
import com.micro.ai.auth.dto.MenuUpdateRequest;
import com.micro.ai.auth.dto.VbenMenuDTO;
import com.micro.ai.auth.service.MenuService;
import com.micro.ai.commons.domain.ApiResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.micro.ai.auth.annotation.AuditLogAnnotation;

import java.util.List;

/**
 * 菜单管理控制器
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
@RestController
@RequestMapping("/api/menus")
@Tag(name = "菜单管理", description = "菜单的增删改查、菜单树、权限控制等操作")
public class MenuController {

    @Autowired
    private MenuService menuService;

    /**
     * 创建菜单
     */
    @PostMapping
    @PreAuthorize("hasAuthority('menu:create')")
    @Operation(summary = "创建菜单", description = "创建新的菜单")
    @AuditLogAnnotation(action = "CREATE", resourceType = "MENU", description = "创建菜单")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "创建成功",
            content = @Content(schema = @Schema(implementation = MenuDTO.class))),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "参数错误或菜单编码已存在"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限")
    })
    public ApiResponse<MenuDTO> createMenu(@Valid @RequestBody MenuCreateRequest request) {
        log.info("创建菜单: tenantId={}, code={}, name={}", request.getTenantId(), request.getCode(), request.getName());
        MenuDTO menu = menuService.createMenu(request);
        return ApiResponse.success(menu);
    }

    /**
     * 更新菜单
     */
    @PutMapping("/{menuId}")
    @PreAuthorize("hasAuthority('menu:update')")
    @Operation(summary = "更新菜单", description = "更新指定菜单的信息")
    @AuditLogAnnotation(action = "UPDATE", resourceType = "MENU", description = "更新菜单")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "更新成功",
            content = @Content(schema = @Schema(implementation = MenuDTO.class))),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "参数错误"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "菜单不存在")
    })
    public ApiResponse<MenuDTO> updateMenu(
            @Parameter(description = "菜单ID", required = true) @PathVariable String menuId,
            @Valid @RequestBody MenuUpdateRequest request) {
        log.info("更新菜单: menuId={}", menuId);
        MenuDTO menu = menuService.updateMenu(menuId, request);
        return ApiResponse.success(menu);
    }

    /**
     * 删除菜单
     */
    @DeleteMapping("/{menuId}")
    @PreAuthorize("hasAuthority('menu:delete')")
    @Operation(summary = "删除菜单", description = "删除指定菜单")
    @AuditLogAnnotation(action = "DELETE", resourceType = "MENU", description = "删除菜单")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "删除成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "菜单下有子菜单不能删除"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "菜单不存在")
    })
    public ApiResponse<Void> deleteMenu(
            @Parameter(description = "菜单ID", required = true) @PathVariable String menuId) {
        log.info("删除菜单: menuId={}", menuId);
        menuService.deleteMenu(menuId);
        return ApiResponse.success();
    }

    /**
     * 获取菜单详情
     */
    @GetMapping("/{menuId}")
    @PreAuthorize("hasAuthority('menu:view')")
    @Operation(summary = "获取菜单详情", description = "根据菜单ID获取菜单详细信息")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功",
            content = @Content(schema = @Schema(implementation = MenuDTO.class))),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "菜单不存在")
    })
    public ApiResponse<MenuDTO> getMenuById(
            @Parameter(description = "菜单ID", required = true) @PathVariable String menuId) {
        MenuDTO menu = menuService.getMenuById(menuId);
        return ApiResponse.success(menu);
    }

    /**
     * 根据编码获取菜单
     */
    @GetMapping("/code/{code}")
    @PreAuthorize("hasAuthority('menu:view')")
    @Operation(summary = "根据编码获取菜单", description = "根据菜单编码获取菜单信息")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功",
            content = @Content(schema = @Schema(implementation = MenuDTO.class))),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "菜单不存在")
    })
    public ApiResponse<MenuDTO> getMenuByCode(
            @Parameter(description = "租户ID", required = true) @RequestParam String tenantId,
            @Parameter(description = "菜单编码", required = true) @PathVariable String code) {
        MenuDTO menu = menuService.getMenuByCode(tenantId, code);
        return ApiResponse.success(menu);
    }

    /**
     * 分页查询菜单
     */
    @GetMapping
    @PreAuthorize("hasAuthority('menu:view')")
    @Operation(summary = "分页查询菜单", description = "根据条件分页查询菜单列表")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限")
    })
    public ApiResponse<Page<MenuDTO>> listMenus(
            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1") int pageNum,
            @Parameter(description = "每页数量", example = "10") @RequestParam(defaultValue = "10") int pageSize,
            @Parameter(description = "租户ID", required = true) @RequestParam String tenantId,
            @Parameter(description = "关键词（名称/编码/描述）") @RequestParam(required = false) String keyword,
            @Parameter(description = "状态") @RequestParam(required = false) String status,
            @Parameter(description = "父菜单ID") @RequestParam(required = false) String parentId) {
        Page<MenuDTO> page = menuService.listMenus(pageNum, pageSize, tenantId, keyword, status, parentId);
        return ApiResponse.success(page);
    }

    /**
     * 获取所有菜单（不分页）
     */
    @GetMapping("/all")
    @PreAuthorize("hasAuthority('menu:view')")
    @Operation(summary = "获取所有菜单", description = "获取所有活跃菜单列表（不分页）")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限")
    })
    public ApiResponse<List<MenuDTO>> getAllMenus(
            @Parameter(description = "租户ID", required = true) @RequestParam String tenantId) {
        List<MenuDTO> menus = menuService.getAllMenus(tenantId);
        return ApiResponse.success(menus);
    }

    /**
     * 获取菜单树
     */
    @GetMapping("/tree")
    //@PreAuthorize("hasAuthority('menu:view')")
    @Operation(summary = "获取菜单树", description = "获取菜单的树形结构")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限")
    })
    public ApiResponse<List<MenuDTO>> getMenuTree(
            @Parameter(description = "租户ID", required = true) @RequestParam String tenantId,
            @Parameter(description = "父菜单ID") @RequestParam(required = false) String parentId,
            @Parameter(description = "语言代码") @RequestParam(required = false) String locale) {
        List<MenuDTO> tree = menuService.getMenuTree(tenantId, parentId, locale);
        return ApiResponse.success(tree);
    }

    /**
     * 获取用户可访问的菜单
     */
    @GetMapping("/user/{userId}")
    @PreAuthorize("hasAuthority('menu:view')")
    @Operation(summary = "获取用户菜单", description = "获取用户可访问的菜单列表")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "用户不存在")
    })
    public ApiResponse<List<MenuDTO>> getUserMenus(
            @Parameter(description = "用户ID", required = true) @PathVariable String userId,
            @Parameter(description = "租户ID", required = true) @RequestParam String tenantId) {
        List<MenuDTO> menus = menuService.getUserMenus(userId, tenantId);
        return ApiResponse.success(menus);
    }

    /**
     * 获取用户可访问的菜单树
     */
    @GetMapping("/user/{userId}/tree")
    @PreAuthorize("hasAuthority('menu:view')")
    @Operation(summary = "获取用户菜单树", description = "获取用户可访问的菜单树形结构")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "用户不存在")
    })
    public ApiResponse<List<MenuDTO>> getUserMenuTree(
            @Parameter(description = "用户ID", required = true) @PathVariable String userId,
            @Parameter(description = "租户ID", required = true) @RequestParam String tenantId,
            @Parameter(description = "语言代码") @RequestParam(required = false) String locale) {
        List<MenuDTO> tree = menuService.getUserMenuTree(userId, tenantId, locale);
        return ApiResponse.success(tree);
    }

    /**
     * 获取用户菜单（Vben 标准格式）
     * 直接返回符合 Vben Admin 框架要求的菜单格式
     */
    @GetMapping("/user/{userId}/vben")
    @PreAuthorize("hasAuthority('menu:view')")
    @Operation(summary = "获取用户菜单（Vben格式）", description = "返回符合 Vben Admin 标准的菜单格式")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "用户不存在")
    })
    public ApiResponse<List<VbenMenuDTO>> getUserMenuTreeVben(
            @Parameter(description = "用户ID", required = true) @PathVariable String userId,
            @Parameter(description = "租户ID", required = true) @RequestParam String tenantId,
            @Parameter(description = "语言代码") @RequestParam(required = false) String locale) {
        List<VbenMenuDTO> tree = menuService.getUserMenuTreeVben(userId, tenantId, locale);
        return ApiResponse.success(tree);
    }

    /**
     * 获取角色可访问的菜单
     */
    @GetMapping("/role/{roleId}")
    @PreAuthorize("hasAuthority('menu:view')")
    @Operation(summary = "获取角色菜单", description = "获取角色可访问的菜单列表")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "角色不存在")
    })
    public ApiResponse<List<MenuDTO>> getRoleMenus(
            @Parameter(description = "角色ID", required = true) @PathVariable String roleId,
            @Parameter(description = "租户ID", required = true) @RequestParam String tenantId) {
        List<MenuDTO> menus = menuService.getRoleMenus(roleId, tenantId);
        return ApiResponse.success(menus);
    }

    /**
     * 检查用户菜单访问权限
     */
    @GetMapping("/check/{userId}/{menuCode}")
    @Operation(summary = "检查用户菜单权限", description = "检查用户是否有指定菜单的访问权限")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "用户不存在")
    })
    public ApiResponse<Boolean> hasMenuAccess(
            @Parameter(description = "用户ID", required = true) @PathVariable String userId,
            @Parameter(description = "菜单编码", required = true) @PathVariable String menuCode,
            @Parameter(description = "租户ID", required = true) @RequestParam String tenantId) {
        boolean hasAccess = menuService.hasMenuAccess(userId, menuCode, tenantId);
        return ApiResponse.success(hasAccess);
    }

    /**
     * 更新菜单排序
     */
    @PutMapping("/{menuId}/sort")
    @PreAuthorize("hasAuthority('menu:update')")
    @Operation(summary = "更新菜单排序", description = "更新菜单的排序")
    @AuditLogAnnotation(action = "UPDATE", resourceType = "MENU", description = "更新菜单排序")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "更新成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "菜单不存在")
    })
    public ApiResponse<Void> updateMenuSort(
            @Parameter(description = "菜单ID", required = true) @PathVariable String menuId,
            @Parameter(description = "排序", required = true) @RequestParam Integer sortOrder) {
        menuService.updateMenuSort(menuId, sortOrder);
        return ApiResponse.success();
    }

    /**
     * 批量更新菜单排序
     */
    @PutMapping("/batch-sort")
    @PreAuthorize("hasAuthority('menu:update')")
    @Operation(summary = "批量更新菜单排序", description = "批量更新菜单的排序")
    @AuditLogAnnotation(action = "UPDATE", resourceType = "MENU", description = "批量更新菜单排序")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "更新成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "参数错误"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限")
    })
    public ApiResponse<Void> batchUpdateMenuSort(
            @Parameter(description = "菜单ID列表", required = true) @RequestParam List<String> menuIds,
            @Parameter(description = "排序列表", required = true) @RequestParam List<Integer> sortOrders) {
        menuService.batchUpdateMenuSort(menuIds, sortOrders);
        return ApiResponse.success();
    }

    /**
     * 复制菜单
     */
    @PostMapping("/{sourceMenuId}/copy")
    @PreAuthorize("hasAuthority('menu:create')")
    @Operation(summary = "复制菜单", description = "复制指定菜单")
    @AuditLogAnnotation(action = "CREATE", resourceType = "MENU", description = "复制菜单")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "复制成功",
            content = @Content(schema = @Schema(implementation = MenuDTO.class))),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "源菜单不存在")
    })
    public ApiResponse<MenuDTO> copyMenu(
            @Parameter(description = "源菜单ID", required = true) @PathVariable String sourceMenuId,
            @Parameter(description = "目标父菜单ID") @RequestParam(required = false) String targetParentId,
            @Parameter(description = "租户ID", required = true) @RequestParam String tenantId) {
        MenuDTO menu = menuService.copyMenu(sourceMenuId, targetParentId, tenantId);
        return ApiResponse.success(menu);
    }

    /**
     * 移动菜单
     */
    @PutMapping("/{menuId}/move")
    @PreAuthorize("hasAuthority('menu:update')")
    @Operation(summary = "移动菜单", description = "移动菜单到新的父菜单下")
    @AuditLogAnnotation(action = "UPDATE", resourceType = "MENU", description = "移动菜单")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "移动成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "菜单不存在")
    })
    public ApiResponse<Void> moveMenu(
            @Parameter(description = "菜单ID", required = true) @PathVariable String menuId,
            @Parameter(description = "目标父菜单ID") @RequestParam(required = false) String targetParentId,
            @Parameter(description = "租户ID", required = true) @RequestParam String tenantId) {
        menuService.moveMenu(menuId, targetParentId, tenantId);
        return ApiResponse.success();
    }
}
